import logging
import socket
from collections import Counter
from threading import Thread, Event

from flask import Flask, Response, request

from SubFunction import *
from inference_old import GenModule

logger = logging.getLogger("yolov5")
logger.setLevel(level=logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler()
console.setLevel(logging.INFO)

logger.addHandler(handler)
logger.addHandler(console)

app = Flask(__name__)

weights_dict = {
    '1': [r'D:\desktop\ketangEnd\ketang_end\ketang_data\weights\front2.pt'],
    '2': [r'G:\project\flask_ketang_huizong_xiugai_mulgpu\weights\back2.pt'],
}
# alarm type请在config.ini中查找自己的数字
func_dict = {
    '1': GenModule,  # 学生
    '2': GenModule,  # 教师
}
program = {}
send_data = None
is_class = 0
camera_list = []
camera_map = {}
thread_wait = False
started_evt = Event()


# qq = queue.Queue()  # 定义消息队列

def workThred(hoisting, person_type, started_evt):
    print('countdown starting')

    global send_data
    global is_class
    global camera_map
    global num
    num = 0
    while True:
        if thread_wait:
            started_evt.wait()
            print("主线程暂停")

            # 在此添加退出前要做的工作，如保存文件等
            # 新
        start_time = time.time()
        send_data = hoisting.execute_func()
        camera_map = hoisting.camera_map
        hoisting.class_is = is_class
        # 判断是否上下课，并发送图片
        if hoisting.class_is == 1:
            hoisting.clear_variable()
            is_class = 0
        if hoisting.class_is == 2:
            if person_type == '2':
                hoisting.send_points()
            is_class = 0
        # if not hoisting.q.empty():
        #     Thread(target=hoisting.senf_m).start()
        Thread(target=hoisting.senf_m).start()
        end_time = round(time.time() - start_time, 3)
        num = num + 1
        print(f"第{num}帧 总的推理时间：", end_time)
        # else:
        #     print("网络已中断，请检测网络连接................")


def workthread1(hoisting, names):
    while True:
        hoisting.resutl_save(names)


def workthread2(hoisting):
    while True:
        hoisting.save_img()


def isNetChainOK(testserver):
    s = socket.socket()
    s.settimeout(3)
    try:
        status = s.connect_ex(testserver)
        if status == 0:
            s.close()
            return True
        else:
            return False
    except Exception as e:
        return False


def judgeNet(testserver=('www.baidu.com', 443)):
    isOK = isNetChainOK(testserver)
    return isOK


@app.route('/recover', methods=['GET'])
def recover():
    started_evt.set()
    data = {
        "code": 200,
        "msg": "主线程恢复",
        "data": {}
    }
    return json.dumps(data)


def common_fun(hoisting, person_type):
    print("开始执行")
    t = Thread(target=workThred, args=(hoisting, person_type, started_evt), daemon=True)
    t.start()
    print('countdown is running')
    data = {
        "code": 200
    }
    return json.dumps(data)


def gen1(type):
    while True:
        if len(camera_map) != 0:
            frame = camera_map[type]
        else:
            frame = 2
            frame.to_bytes(4, byteorder='little', signed=True)
        # 使用generator函数输出视频流， 每次请求输出的content类型是image/jpeg
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')


@app.route('/get_stream', methods=['GET', 'POST'])  # 这个地址返回视频流响应
def test_redis():
    alarm_type = request.args.get("type")
    print("视频流参数：", alarm_type)
    return Response(gen1(alarm_type), mimetype='multipart/x-mixed-replace; boundary=frame')


@app.route('/class_begin', methods=['GET'])
def class_begin():
    global is_class
    is_class = 1
    data = {
        "code": 200,
        "msg": "success",
        "data": {}
    }
    return json.dumps(data)


@app.route('/class_end', methods=['GET'])
def class_end():
    global is_class
    is_class = 2
    data = {
        "code": 200,
        "msg": "success",
        "data": {}
    }
    return json.dumps(data)


@app.route('/getBehaviorNum', methods=['GET', 'POST'])
def getbehaviornum():
    camera_id = request.args.get("camera_id")
    print("camera_id:::::", camera_id)
    f = camera_list.index(camera_id)
    data = send_data[f]
    send_json = {
        "camera_id": camera_id,
        "learing": 0,
        'hand': 0,
        "sleep": 0,
        "stand": 0,
        "phone": 0
    }
    data = np.array(data)
    data_json = Counter(data)
    send_json["camera_id"] = camera_id
    if data_json["L"]:
        send_json["learing"] = data_json["L"]
    if data_json["hand"]:
        send_json["hand"] = data_json["hand"]
    if data_json["sleep"]:
        send_json["sleep"] = data_json["sleep"]
    if data_json["stand"]:
        send_json["stand"] = data_json["stand"]
    if data_json["phone"]:
        send_json["phone"] = data_json["phone"]
    print("-------正在统计当前人数--------")
    data = {
        "code": 200,
        "msg": "数据获取成功",
        "data": send_json}
    return json.dumps(data)


@app.route('/stop', methods=["GET"])  # 这个地址返回视频流响应
def stop():
    global thread_wait
    thread_wait = True
    print("结束执行")
    data = {
        "code": 200,
        "msg": "算法结束",
        "data": {}
    }
    return json.dumps(data)


@app.route('/start', methods=['GET', 'POST'])  # 这个地址返回视频流响应
def start():
    global is_class
    global camera_list
    src_list = []
    person_type = ''
    data = request.get_data()

    data = json.loads(data)
    print("daa:::::::::::;", data)
    for data_in in data:
        src_list.append(data_in['path'])
        camera_list.append(data_in['camera_id'])
        person_type = data_in["person_type"]
    Func = func_dict[str(person_type)]  # 类
    sub_weight = weights_dict[str(person_type)]  # 权重
    sub_addr = src_list
    params = {"camera_id": 0, "created_at": "", "data_id": "", 'data': "", "person_type": str(person_type),
              "event_level": "", "event_type": "", "screenshot_url": "", "video_url": ""}
    personTrack = False
    imagesize = 1280
    # 教师行为

    if person_type == 2:
        personTrack = True
        imagesize = 640
    sub_func = Func(src_list=sub_addr,  # 视频源
                    weight=sub_weight,  # 权重
                    params=params,
                    fps_show=False,  # fps显示 # 丢帧模拟
                    track=personTrack,  # 跟踪
                    msg_send=True,  # 警报发送
                    imagesize=imagesize,
                    half=True,
                    camera_list=camera_list,  # 摄像头数组
                    Time_time=0,  # 隔多少帧检测一次
                    device='0',
                    COUNTS=5,  # 间隔30帧
                    FramesListening=5,  # 听讲人数，间隔5秒
                    FramesPeople=5,  # 教室人数，间隔一分钟
                    )

    status = common_fun(hoisting=sub_func, person_type=person_type)
    return status


if __name__ == '__main__':
    # app.run()
    app.run(host='0.0.0.0', port=5020, debug=True)
